﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;

using NHibernate;
using NHibernate.Type;
using ProjectBase.Core;

namespace ProjectBase.Data.NH
{
    [Serializable]
    public class InnerFilter
    {
        #region members
        IList<Filter> _filters;
        #endregion members

        #region Constructor
        public InnerFilter(string tableName, string selectColumnName, string whereColumnName)
        {
            Contract.Requires(tableName.IsNotEmpty());
            Contract.Requires(selectColumnName.IsNotEmpty());
            Contract.Requires(whereColumnName.IsNotEmpty());
            TableName = tableName;
            SelectColumnName = selectColumnName;
            WhereColumnName = whereColumnName;
        }
        #endregion Constructor

        #region Fluently
        public virtual InnerFilter SetValue(int whereColumnValue)
        {
            WhereColumnValue = whereColumnValue;
            return this;
        }
        public virtual InnerFilter SetValue(IPersistentObjectWithTypedId<int> whereColumnEntity)
        {
            Contract.Requires(whereColumnEntity.Is());
            WhereColumnValue = whereColumnEntity.ID;
            return this;
        }
        /// <summary>
        ///  Adds filter to inner entity: SELECT SelectColumn FROM  TableName
        ///     WHERE thisFilter.columnName LIKE phrase
        /// </summary>
        /// <param name="columnName">if 'columnName' null or empty, filter won't be added</param>
        /// <param name="phrase">if 'value' null or empty, filter won't be added</param>
        /// <param name="sign">if null or not provided: LIKE is used</param>
        /// <returns></returns>
        public virtual InnerFilter AddFilterString(string columnName, string phrase, string sign = null)
        {
            if (phrase.IsEmpty() || columnName.IsEmpty())
            {
                return this;
            }
            Filters.Add(new Filter
            {
                ColumnName = columnName,
                NType = NHibernateUtil.String,
                Sign = sign ?? "LIKE",
                Value = phrase.Replace('*', '%'),
            });
            return this;
        }
        #endregion Fluently

        #region properties
        public readonly string TableName;
        public readonly string SelectColumnName;
        public readonly string WhereColumnName;

        public virtual int? WhereColumnValue { get; set; }
        public virtual bool NotIn { get; set; }

        public virtual IList<Filter> Filters
        {
            get { return _filters ?? (_filters = new List<Filter>()); }
            set { _filters = value; }
        }
        #endregion properties
    }

    [Serializable]
    public class Filter
    {
        public virtual IType NType { get; set; }
        public virtual string ColumnName { get; set; }
        public virtual object Value { get; set; }
        public virtual string Sign { get; set; }
    }
}